
import java.awt.Dimension;
import java.awt.Toolkit;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JOptionPane;

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/*
 * FrmGame.java
 *
 * Created on 6/Mai/2011, 17:22:19
 */

/**
 *
 * @author Bruno
 */
public class FrmGame extends javax.swing.JFrame {

	private static final int CELL_WIDTH = 63;
	private static final int CELL_HEIGHT = 54;
	private final ImageIcon cellIcon = new javax.swing.ImageIcon(getClass().getResource("/images/hexCell.png"));
	private final ImageIcon cellWhiteIcon = new javax.swing.ImageIcon(getClass().getResource("/images/hexWhiteCell.png"));
	private final ImageIcon cellBlackIcon = new javax.swing.ImageIcon(getClass().getResource("/images/hexBlackCell.png"));

	private JLabel[][] board; // Células visíveis
	private CellLabel[][] labels; // Labels sobre as células onde se pode clicar
	private boolean clickEnabled = false; // Se o utilizador pode clicar nas células para efectuar uma jogada

    /** Creates new form FrmGame */
    public FrmGame() {
        initComponents();

		// Desenhar o tabuleiro no painel "pnlGame"
		int size = Hex.board.getSize();
		int hsize = size * CELL_WIDTH + (size - 1) * (CELL_WIDTH / 2) + 1;
		int vsize = size * CELL_HEIGHT + 23;
		pnlGame.setPreferredSize(new Dimension(hsize, vsize));

		board = new JLabel[size][size];
		labels = new CellLabel[size][size];
		for(int i = 0; i < size; i++)
			for(int j = 0; j < size; j++) {
				// Adicionar a célula clicável
				CellLabel label = new CellLabel(i, j);
				labels[i][j] = label;
				pnlGame.add(label);

				int x = j * CELL_WIDTH + i * (CELL_WIDTH / 2) + 2;
				int y = i * CELL_HEIGHT + 18;

				label.setLocation(x, y);
				label.setSize(60, 47);

				label.addMouseListener(new MouseListener() {
					public void mouseClicked(MouseEvent e) {
						cellLabelMouseClicked(e);
					}

					public void mousePressed(MouseEvent e) { }
					public void mouseReleased(MouseEvent e) { }
					public void mouseEntered(MouseEvent e) { }
					public void mouseExited(MouseEvent e) { }
				});

				
				// Adicionar a célula (imagem) visível
				JLabel cell = new JLabel();
				board[i][j] = cell;
				cell.setIcon(cellIcon);
				pnlGame.add(cell);

				x = j * CELL_WIDTH + i * (CELL_WIDTH / 2);
				y = i * CELL_HEIGHT;

				cell.setLocation(x, y);
				cell.setSize(80, 80);
			}

		pack();

		Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
		setLocation(screenSize.width/2 - getWidth()/2, screenSize.height/2 - getHeight()/2);

		refreshLabels();
		makeOrWaitMove();
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        jPanel1 = new javax.swing.JPanel();
        cmdExit = new javax.swing.JButton();
        jPanel2 = new javax.swing.JPanel();
        lblTitle = new javax.swing.JLabel();
        lblCurrentPlayer = new javax.swing.JLabel();
        lblObjective = new javax.swing.JLabel();
        pnlGame = new javax.swing.JPanel();

        setDefaultCloseOperation(javax.swing.WindowConstants.DO_NOTHING_ON_CLOSE);
        setTitle("HEX");
        addWindowListener(new java.awt.event.WindowAdapter() {
            public void windowClosing(java.awt.event.WindowEvent evt) {
                formWindowClosing(evt);
            }
        });

        cmdExit.setText("Sair");
        cmdExit.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                cmdExitActionPerformed(evt);
            }
        });
        jPanel1.add(cmdExit);

        getContentPane().add(jPanel1, java.awt.BorderLayout.SOUTH);

        jPanel2.setLayout(new java.awt.BorderLayout(0, 5));

        lblTitle.setFont(new java.awt.Font("Tahoma", 1, 36)); // NOI18N
        lblTitle.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
        lblTitle.setText("HEX");
        jPanel2.add(lblTitle, java.awt.BorderLayout.NORTH);

        lblCurrentPlayer.setFont(new java.awt.Font("Tahoma", 0, 14)); // NOI18N
        lblCurrentPlayer.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
        lblCurrentPlayer.setText("<Jogador actual: ********>");
        jPanel2.add(lblCurrentPlayer, java.awt.BorderLayout.CENTER);

        lblObjective.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
        lblObjective.setText("<Faça um caminho que conecte os lados ******** e ******** do tabuleiro.>");
        jPanel2.add(lblObjective, java.awt.BorderLayout.SOUTH);

        getContentPane().add(jPanel2, java.awt.BorderLayout.NORTH);

        pnlGame.setLayout(null);
        getContentPane().add(pnlGame, java.awt.BorderLayout.CENTER);

        pack();
    }// </editor-fold>//GEN-END:initComponents

	private void cmdExitActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cmdExitActionPerformed
		exit();
	}//GEN-LAST:event_cmdExitActionPerformed

	private void formWindowClosing(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_formWindowClosing
		exit();
	}//GEN-LAST:event_formWindowClosing

	private void cellLabelMouseClicked(MouseEvent e) {
		if(!clickEnabled)
			return;

		CellLabel label = (CellLabel)e.getSource();
		int line = label.getLine();
		int col = label.getColumn();
		Move move = new Move(line, col);

		if(!Hex.board.isValidMove(move)) {
			JOptionPane.showMessageDialog(null, "Essa célula já está ocupada!", "HEX", JOptionPane.ERROR_MESSAGE);
			return;
		}

		clickEnabled = false;
		makeMove(move);

		Hex.changeTurn();
		refreshLabels();
		makeOrWaitMove();
	}

	private void exit() {
		if(JOptionPane.showConfirmDialog(null, "Quer mesmo sair deste jogo?", "HEX", JOptionPane.OK_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE) == JOptionPane.OK_OPTION) {
			Hex.hexGraphical.frmMenu.setVisible(true);
			setVisible(false);
			dispose();
		}
	}

	private void refreshLabels() {
		if(Hex.currentPlayer == Color.WHITE) {
			lblCurrentPlayer.setText("Jogador actual: Branco");
			lblObjective.setText("Faça um caminho que conecte os lados esquerdo e direito do tabuleiro.");
		}
		else {
			lblCurrentPlayer.setText("Jogador actual: Preto");
			lblObjective.setText("Faça um caminho que conecte os lados superior e inferior do tabuleiro.");
		}
	}

	private void makeOrWaitMove() {
		if(Hex.board.isGameOver()) {
			lblCurrentPlayer.setText("Fim do jogo");
			if(Hex.board.getWinner() == Color.WHITE) {
				lblObjective.setText("Vitória do jogador branco!");
				JOptionPane.showMessageDialog(null, "Fim do jogo\nVitória do jogador branco!", "Hex", JOptionPane.PLAIN_MESSAGE);
			}
			else {
				lblObjective.setText("Vitória do jogador preto!");
				JOptionPane.showMessageDialog(null, "Fim do jogo\nVitória do jogador preto!", "Hex", JOptionPane.PLAIN_MESSAGE);
			}
			clickEnabled = false;
			return;
		}

		int playerType = 0;
		if(Hex.currentPlayer == Color.WHITE)
			playerType = Hex.whitePlayer;
		else
			playerType = Hex.blackPlayer;

		if(playerType == Player.HUMAN)
			clickEnabled = true;
		else {
			clickEnabled = false;

			// Obter a jogada da IA numa thread para não congelar a janela gráfica
			final int pType = playerType;
			(new Thread(){
				public void run() {
					Move move = ComputerAI.makeMove(Hex.board, Hex.currentPlayer, pType);
					makeMove(move);

					Hex.changeTurn();
					refreshLabels();
					makeOrWaitMove();
				}

			}).start();
		}
	}

	private void makeMove(Move move) {
		Hex.board.placePiece(Hex.currentPlayer, move);
		if(Hex.currentPlayer == Color.WHITE)
			board[move.getLine()][move.getColumn()].setIcon(cellWhiteIcon);
		else
			board[move.getLine()][move.getColumn()].setIcon(cellBlackIcon);
	}

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton cmdExit;
    private javax.swing.JPanel jPanel1;
    private javax.swing.JPanel jPanel2;
    private javax.swing.JLabel lblCurrentPlayer;
    private javax.swing.JLabel lblObjective;
    private javax.swing.JLabel lblTitle;
    private javax.swing.JPanel pnlGame;
    // End of variables declaration//GEN-END:variables

}

class CellLabel extends JLabel {
	private int line, column;

	CellLabel(int line, int column) {
		super();
		this.line = line;
		this.column = column;
	}

	int getLine() {
		return line;
	}

	int getColumn() {
		return column;
	}
}